define([
    'angular',
    'angularAMD',
    'config',
    'core/init'
], function (angular, angularAMD, config) {
    var mainApp = angular.module('app', ['app.main']);

    mainApp.constant('Config', config);

    mainApp.config(['$httpProvider', '$routeProvider', function($httpProvider, $routeProvider) {
        // http
        $httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
        // interceptor
        $httpProvider.interceptors.push(['$rootScope', '$timeout', '$interval', '$injector', 'AuthFactory',
            function($rootScope, $timeout, $interval, $injector, AuthFactory) {
            var isLoaded = false;
            return {
                request: function(request) {
                    $rootScope.loadings++;
                    // load loading
                    if (!isLoaded) {
                        isLoaded = true;
                        $timeout(function() {
                            $rootScope.loading = $rootScope.loadings > 0;
                        }, 1000).then(function() {
                            var promise = $interval(function() {
                                if ($rootScope.loadings == 0) {
                                    $rootScope.loading = false;
                                    isLoaded = false;
                                    $interval.cancel(promise);
                                }
                            }, 200);
                        });
                    }
                    return request;
                },
                requestError: function(rejection) {
                    $rootScope.loadings--;
                    return rejection;
                },
                response: function(response) {
                    $rootScope.loadings--;
                    return response;
                },
                responseError: function(rejection) {
                    $rootScope.loadings--;
                    if (rejection.status == -1) {
                        $injector.get('Dialog').$alert('服务器连接超时！');
                    }
                    // reject
                    if (rejection.status == 403) {
                        AuthFactory.setAuthenticated(false);
                    }
                    // error
                    if (rejection.status == 500) {
                        $injector.get('Dialog').$alert(rejection.data.message);
                    }
                    return rejection;
                }
            };
        }]);

        // set default route URL
        $routeProvider.otherwise({ redirectTo: config.defaultPath });
    }]);

    // add application controller
    angular.element(document).ready(function() {
        angular.element(document.body).attr('ng-controller', 'AppController');
    });
    mainApp.controller('AppController', ['$rootScope', '$scope', '$location', 'Dialog', 'AuthFactory', 'AuthService',
        function($rootScope, $scope, $location, Dialog, AuthFactory, AuthService) {
        $rootScope.loading = false;
        $rootScope.loadings = 0;
        $rootScope.authenticated = AuthFactory.isAuthenticated();

        var copyrightToYear = new Date().getFullYear();
        if (copyrightToYear > config.copyrightFromYear) {
            $rootScope.copyrightYear = config.copyrightFromYear + '~' + copyrightToYear;
        } else {
            $rootScope.copyrightYear = config.copyrightFromYear;
        }

        $rootScope.$watch(function() {
            return AuthFactory.isAuthenticated();
        }, function(authenticated) {
            $rootScope.authenticated = authenticated;
            if (authenticated) {
                $scope.parameters = AuthFactory.getParameters();
            } else if (config.authenticatedPaths.indexOf($location.path()) < 0) {
                var targetPath = $location.path();
                var defaultTargetUrl = $location.absUrl().replace(/#\/.*$/, '#' + config.defaultPath);
                if (targetPath == '') {
                    AuthFactory.setParameters({
                        target: defaultTargetUrl
                    });
                    $location.url('/login').replace();
                } else {
                    AuthFactory.setParameters({
                        target: AuthFactory.getParameters().logout ? defaultTargetUrl : $location.absUrl()
                    });
                    location.href = '?reload#/login';
                }
            }
        }, true);

        $rootScope.$on("$locationChangeStart", function(event, next, current) {
            refreshNavbar();
            for (var index in config.authenticatedPaths) {
                if (next.indexOf(config.authenticatedPaths[index]) >= 0) {
                    AuthFactory.setAuthenticated(false);
                    break;
                }
            }
        });

        $rootScope.initNavbar = function() {
            refreshNavbar();
            angular.element('.navbar-nav > li').each(function() {
                var $this = angular.element(this);
                $this.click(function() {
                    angular.element('.navbar-nav > li').removeClass('active');
                    $this.addClass('active');
                });
            });
        };

        function refreshNavbar() {
            angular.element('.navbar-nav > li').each(function() {
                var $this = angular.element(this);
                $this.removeClass('active');
                if ($this.find('a').attr('href').indexOf($location.path()) >= 0) {
                    $this.addClass('active');
                }
            });
        }

        $rootScope.initWidget = function() {
            var $window = angular.element(window);
            var $scroller = angular.element('#scroller');
            $window.scroll(function () {
                if ($window.scrollTop() > 100) {
                    if (!$scroller.is(':visible')) {
                        $scroller.fadeIn(300);
                    }
                } else {
                    $scroller.fadeOut(300);
                }
            });
            $scroller.click(function() {
                angular.element(document.body).animate({
                    scrollTop: 0
                }, 300);
            });
        };
        
        $rootScope.search = function() {
            var keyword = angular.element('#keyword').val();
            if (keyword != '') {
                $location.url('/search/' + keyword);
            }
        };

        $rootScope.logout = function() {
            AuthService.logout().then(function(resp) {
                AuthFactory.setParameters({
                    logout: true,
                    authenticated: false
                });
            });
        };

        $rootScope.editPassword = function() {
            Dialog.$open().editPassword().then(function(data) {
                if (data.success) {
                    $rootScope.logout();
                }
            });
        };
    }]);

    return angularAMD.bootstrap(mainApp);
});
